#pragma once

#include <rocksdb/db.h>

#include <mutex>
#include <vector>

class ScopeLockMgr {
 public:
  explicit ScopeLockMgr(int hash_power);
  ~ScopeLockMgr();

  unsigned Size();
  void Lock(const rocksdb::Slice &key);
  void UnLock(const rocksdb::Slice &key);

 private:
  int hash_power_;
  int hash_mask_;
  std::vector<std::shared_ptr<std::mutex>> mutex_pool_;
  unsigned hash(const rocksdb::Slice &key);
};

class ScopeLock {
 public:
  explicit ScopeLock(ScopeLockMgr *lock_mgr, rocksdb::Slice key)
      : lock_mgr_(lock_mgr), key_(key) {
    lock_mgr->Lock(key_);
  }
  ~ScopeLock() { lock_mgr_->UnLock(key_); }

 private:
  ScopeLockMgr *lock_mgr_ = nullptr;
  rocksdb::Slice key_;
};
